package com.wink.admin.controller;


import cn.hutool.core.util.RandomUtil;
import com.wink.admin.aspect.annotation.Log;
import com.wink.admin.aspect.annotation.RepeatSubmit;
import com.wink.admin.common.response.ApiResponse;
import com.wink.admin.config.PersonConfig;
import com.wink.admin.entity.SysUser;
import com.wink.admin.redis.RedisService;
import com.wink.admin.service.impl.SysUserServiceImpl;
import com.wink.admin.utils.ResponseUtils;
import com.wink.admin.utils.TokenUtils;
import com.wink.admin.utils.thread.CustomThreadPoolManager;
import com.wink.autoconfiguration.myaspect.RepeatSubmit2;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import java.util.Objects;


/**
 * user controller
 *
 * @author xw
 * @date 2020/10/27 13:48
 */
@Slf4j
@RestController
@RequestMapping("/user")
@AllArgsConstructor
public class UserController {

    private final SysUserServiceImpl userService;

    private final RedisService redisService;

    private final PersonConfig personConfig;


    //  TODO: 2020/11/9 WINK 强烈推荐两个插件 apidoc、Document Assistant 代码无侵入生成接口文档

    /**
     * @api {POST} /user/login login
     * @apiVersion 1.0.0
     * @apiGroup UserController
     * @apiName login
     * @apiDescription 登陆
     * @apiParam (请求参数) {String} userName 用户名
     * @apiParam (请求参数) {String} password password
     * @apiParam (请求参数) {Number} id
     * @apiParam (请求参数) {Number} isDeleted
     * @apiParam (请求参数) {Number} createdDate
     * @apiParam (请求参数) {Number} lastModifyDate
     * @apiParamExample 请求参数示例
     * password=VRF4Yr&createdDate=null&isDeleted=619&id=9194&userName=x4xfyDZJ&lastModifyDate=null
     * @apiSuccess (响应结果) {Number} code
     * @apiSuccess (响应结果) {String} message
     * @apiSuccess (响应结果) {Object} data
     * @apiSuccess (响应结果) {String} requestId
     * @apiSuccessExample 响应结果示例
     * {"code":8157,"data":{},"requestId":"01Nm1d","message":"9EtRE8H"}
     */
    @RepeatSubmit(keys = "#sysUser.userName")
    @PostMapping("/login")
    public ApiResponse login(SysUser sysUser) {
        log.debug("测试debug！");
        log.info("测试info！");
        log.warn("测试warn！");
        log.error("测试error！");
        String authToken = TokenUtils.createAuthToken(sysUser.getUserName(), TokenUtils.secret, sysUser, 7000000L);
        return ResponseUtils.ok(authToken);
    }

    @GetMapping("/getList")
    @Log(value = "用户列表")
    public ApiResponse getList() {
        return ResponseUtils.ok(userService.getList());
    }

    //=======================测试防止重复提交注解=================================//

    @RepeatSubmit
    @GetMapping("/getOne")
    public ApiResponse getOne(Long id) {
        return ResponseUtils.ok(userService.getOne(id));
    }

    @RepeatSubmit(keys = "#id")
    @GetMapping("/getOne2")
    public ApiResponse getOne2(Long id) {
        return ResponseUtils.ok(userService.getOne(id));
    }

    @PostMapping("/addUser")
    @Log(value = "添加用户")
    public ApiResponse addUser(SysUser sysUser) {
        return ResponseUtils.ok(userService.addUser(sysUser));
    }

    @PostMapping("/deleteUser")
    public ApiResponse deleteUser(Long id) {
        return ResponseUtils.ok(userService.deleteUser(id));
    }

    @PostMapping("/updateUser")
    public ApiResponse updateUser(Long id, String password) {
        CustomThreadPoolManager.getInstance().runThread(() -> userService.updateUser(id, password));
        return ResponseUtils.ok();
    }

    @PostMapping("/testRedisMsg")
    public ApiResponse testRedisMsg(String msg) {
        redisService.sendMessage("abc", msg + "--->abc");
        redisService.sendMessage("efg", msg + "--->efg");
        redisService.sendMessage("ccccc", msg + "--->ccccc");
        return ResponseUtils.ok();
    }

    //=======================线程池=================================//

    /**
     * 线程池使用
     *
     * @param msg 味精
     * @return {@link ApiResponse}
     */
    @PostMapping("/test01Async")
    public ApiResponse test01Async(String msg) {
        CustomThreadPoolManager.getInstance().runThread(() -> {
            log.error("test01Async->thread name：{}，异步线程使用：{}", Thread.currentThread().getName(), msg);
        });
        return ResponseUtils.ok();
    }

    /**
     * 线程池使用
     *
     * @param msg 味精
     * @return {@link ApiResponse}
     */
    @PostMapping("/test02Async")
    public ApiResponse test02Async(String msg) {
        userService.test02Async(msg);
        return ResponseUtils.ok();
    }


    //=======================测试加载properties=================================//


    @PostMapping("/testReloadProperties")
    public ApiResponse testReloadProperties() {
        String name = personConfig.getName();
        log.warn("personConfig.getName()" + name);
        return ResponseUtils.ok(name);
    }

    //=======================测试自定义starter=================================//


    @PostMapping("/testStarter")
    @RepeatSubmit2(expire = 60)
    public ApiResponse testStarter() {
        return ResponseUtils.ok();
    }

    //=======================短链接生成=================================//

    @PostMapping("/shortUrl")
    public ApiResponse shortUrl(@NotBlank(message = "url不能为空！")
                                @Pattern(regexp = "^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]",
                                        message = "url格式有误")
                                        String url) {
        String key = RandomUtil.randomString(7);
        redisService.set(key, url,72000L);
        HttpServletRequest request = ((ServletRequestAttributes) Objects
                .requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        return ResponseUtils.ok(request.getScheme() + "://" + request.getServerName() + "/url/" + key);
    }


}
